package com.liujun.microserver.auth2.webjoin.server.user;

import java.net.URI;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import com.liujun.microserver.auth2.webjoin.server.bean.ClientUser;
import com.liujun.microserver.auth2.webjoin.server.bean.EntryItem;
import com.liujun.microserver.auth2.webjoin.server.bean.UserInfo;
import com.liujun.microserver.auth2.webjoin.server.dao.UserRepository;
import com.liujun.microserver.auth2.webjoin.server.oauth.AuthorizationCodeTokenService;
import com.liujun.microserver.auth2.webjoin.server.oauth.OAuth2Token;
import com.liujun.microserver.auth2.webjoin.server.security.ClientUserDetails;

/**
 * 1,实现用于客户端接入远程服务器的核心类
 * 
 * 2,用于服务回调的操作
 * 
 * @author liujun
 * @date 2018/07/01
 */
@Controller
public class MainPage {

	/**
	 * doc:获取code的服务
	 */
	@Autowired
	private AuthorizationCodeTokenService authCodeService;

	/**
	 * doc:用户信息查询
	 */
	@Autowired
	private UserRepository users;

	@GetMapping("/")
	public String home() {
		return "index";
	}

	/**
	 * 回调函数
	 * 
	 * @return
	 */
	@GetMapping("/callback")
	public ModelAndView callback(String code, String state) {
		ClientUserDetails userDetails = (ClientUserDetails) SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		ClientUser clientUser = userDetails.getClientUser();

		OAuth2Token token = authCodeService.getToken(code);
		clientUser.setAccessToken(token.getAccessToken());

		Calendar tokenValidity = Calendar.getInstance();
		tokenValidity.setTime(new Date(Long.parseLong(token.getExpiresIn())));
		clientUser.setAccessTokenValidity(tokenValidity);

		users.save(clientUser);

		return new ModelAndView("redirect:/mainpage");
	}

	@GetMapping("/mainpage")
	public ModelAndView mainPage() {
		// 1, 获取用户
		ClientUserDetails userDetails = (ClientUserDetails) SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		ClientUser user = userDetails.getClientUser();

		// 如果当前用户没有token，则向授权服务器请求，获取code
		if (user.getAccessToken() == null) {
			String endPoint = authCodeService.getCodeEndPoint();
			return new ModelAndView("redirect:" + endPoint);
		}

		user.setEntries(Arrays.asList(new EntryItem("entry 1"), new EntryItem("entry 1")));

		// 调用获取用户信息的接口
		return getUserinfo(user.getAccessToken(), user);
	}

	public ModelAndView getUserinfo(String token, ClientUser user) {

		ModelAndView mv = new ModelAndView("mainpage");
		mv.addObject("user", user);

		RestTemplate restTemplate = new RestTemplate();

		MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
		headers.add("Authorization", "Bearer " + token);
		String endpoint = "http://localhost:8080/api/userinfo";

		RequestEntity<Object> request = new RequestEntity<>(
				// 请求头对象
				headers,
				// 使用get方法请求
				HttpMethod.GET,
				// 调用的API方法
				URI.create(endpoint));

		ResponseEntity<UserInfo> userInfo = restTemplate.exchange(request, UserInfo.class);

		if (userInfo.getStatusCode().is2xxSuccessful()) {
			mv.addObject("userInfo", userInfo.getBody());
		} else {
			throw new RuntimeException("it was not possible to retrieve user profile");
		}

		return mv;
	}
}
